

use std::{fs::File, sync::Mutex};
use lazy_static::lazy_static;
use log::{self, info, error};
use tokio::io::{Error, ErrorKind};

#[derive(Debug, Default)]
pub struct Settings {
    // server
    pub svr_port:u16,

    // postgres
    pub pg_host: String,
    pub pg_port: u16,
    pub pg_user: String,
    pub pg_password: String,

    // minio


    // mongo
    pub mg_host: String,
    pub mg_port: u16,
    pub mg_user: String,
    pub mg_password: String
}

impl Settings {
    pub fn load(&mut self) -> Result<(), tokio::io::Error> {

        let new_err = |err:&str| -> Error {
            Error::new(ErrorKind::Other, err)
        };

        let file = File::open("./settings.json").map_err(|e| {
            error!("open setting file failed");

            new_err(&e.to_string())
        })?;

        let reader = std::io::BufReader::new(file);
        

        let json_doc:serde_json::Value = serde_json::from_reader(reader).map_err(|e| {
            error!("read setting file failed, not a json file ?");
            new_err(&e.to_string())
        })?;

        self.svr_port =  json_doc["server"]["port"].as_i64().ok_or(new_err("value"))? as u16;

        self.pg_host = json_doc["postgres"]["host"].as_str().ok_or(new_err("postgres host parse error"))?.to_string();
        self.pg_port = json_doc["postgres"]["port"].as_i64().ok_or(new_err("postgres port parse error"))? as u16;
        self.pg_user =json_doc["postgres"]["user"].as_str().ok_or(new_err("postgres host parse error"))?.to_string();
        self.pg_password =json_doc["postgres"]["password"].as_str().ok_or(new_err("postgres password parse error"))?.to_string();

        self.mg_host = json_doc["mongodb"]["host"].as_str().ok_or(new_err("mongodb host parse error"))?.to_string();
        self.mg_port = json_doc["mongodb"]["port"].as_i64().ok_or(new_err("mongodb port parse error"))? as u16;
        self.mg_user =json_doc["mongodb"]["user"].as_str().ok_or(new_err("mongodb host parse error"))?.to_string();
        self.mg_password =json_doc["mongodb"]["password"].as_str().ok_or(new_err("mongodb password parse error"))?.to_string();        

        info!("settings: {:?}", self);
     Ok(())
    }
}

// pub setting 
lazy_static!{
    pub static ref APP_SETTINGS: Mutex<Settings> = Mutex::new(Settings::default());
}
